package com.zhonghui.modlules.user.eshopService.Impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eshop.service.Impl.BaseServiceImpl;
import com.zhonghui.common.eshopDomain.ShopUser;
import com.zhonghui.common.eshopDozer.config.IGenerator;
import com.zhonghui.common.eshopEnum.BillDetailEnum;
import com.zhonghui.common.eshopEnum.Brokerage;
import com.zhonghui.common.eshopEnum.ShopCommonEnum;
import com.zhonghui.common.eshopVo.StoreProductQueryVo;
import com.zhonghui.modlules.cart.eshopVo.StoreCartQueryVo;
import com.zhonghui.modlules.order.eshopMapper.StoreOrderMapper;
import com.zhonghui.modlules.order.eshopService.StoreOrderCartInfoService;
import com.zhonghui.modlules.order.eshopVo.StoreOrderCartInfo;
import com.zhonghui.modlules.order.eshopVo.StoreOrderQueryVo;
import com.zhonghui.modlules.shop.eshopService.SystemConfigService;
import com.zhonghui.modlules.user.eshopDomain.SystemUserLevel;
import com.zhonghui.modlules.user.eshopDomain.UserLevel;
import com.zhonghui.modlules.user.eshopMapper.UserBillMapper;
import com.zhonghui.modlules.user.eshopMapper.UserMapper;
import com.zhonghui.modlules.user.eshopService.SystemUserLevelService;
import com.zhonghui.modlules.user.eshopService.UserBillService;
import com.zhonghui.modlules.user.eshopService.UserLevelService;
import com.zhonghui.modlules.user.eshopService.UserService;
import com.zhonghui.modlules.user.eshopVo.UserQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(
        propagation = Propagation.SUPPORTS,
        readOnly = true,
        rollbackFor = {Exception.class}
)
public class UserServiceImpl  extends BaseServiceImpl<UserMapper, ShopUser> implements UserService {
    @Autowired
    private IGenerator generator;
    @Autowired
    private StoreOrderMapper storeOrderMapper;
    @Autowired
    private UserBillMapper userBillMapper;
    @Autowired
    private UserMapper yxUserMapper;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserBillService billService;
    @Autowired
    private StoreOrderCartInfoService storeOrderCartInfoService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private SystemUserLevelService systemUserLevelService;

    public Double[] getUserMoney(Long uid) {
        double sumPrice = this.storeOrderMapper.sumPrice(uid);
        double sumRechargePrice = this.userBillMapper.sumRechargePrice(uid);
        return new Double[]{sumPrice, sumRechargePrice};
    }

    public void setSpread(String spread, long uid){
        if (!StrUtil.isBlank(spread) && NumberUtil.isNumber(spread)) {
            String open = this.systemConfigService.getData("store_brokerage_open");
            if (!StrUtil.isBlank(open) && !ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
                ShopUser userInfo = (ShopUser)this.getById(uid);
                if (!ObjectUtil.isNull(userInfo)) {
                    if (userInfo.getSpreadUid() == null || userInfo.getSpreadUid() <= 0L) {
                        long spreadInt = Long.valueOf(spread);
                        if (spreadInt != 0L) {
                            if (spreadInt != uid) {
                                ShopUser userInfoT = (ShopUser)this.getById(spreadInt);
                                if (!ObjectUtil.isNull(userInfoT)) {
                                    if (userInfoT.getSpreadUid() != uid) {
                                        ShopUser shopUser = ShopUser.builder().spreadUid(spreadInt).spreadTime(new Date()).uid(uid).build();
                                        this.yxUserMapper.updateById(shopUser);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public UserQueryVo getYxUserById(Long uid) {
        return (UserQueryVo)this.generator.convert(this.getById(uid), UserQueryVo.class);
    }

    public void incPayCount(Long uid) {
        this.yxUserMapper.incPayCount(uid);
    }

    public void backOrderBrokerage(StoreOrderQueryVo order) {
        String open = this.systemConfigService.getData("store_brokerage_open");
        if (!StrUtil.isBlank(open) && !ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
            ShopUser userInfo = (ShopUser)this.getById(order.getUid());
            System.out.println("userInfo:" + userInfo);
            if (!ObjectUtil.isNull(userInfo) && userInfo.getSpreadUid() != 0L) {
                ShopUser preUser = (ShopUser)this.getById(userInfo.getSpreadUid());
                BigDecimal brokeragePrice = this.computeProductBrokerage(order, Brokerage.LEVEL_1);
                if (brokeragePrice.compareTo(BigDecimal.ZERO) > 0) {
                    double balance = NumberUtil.add(preUser.getBrokeragePrice(), brokeragePrice).doubleValue();
                    String mark = userInfo.getNickname() + "成功消费" + order.getPayPrice() + "元,奖励推广佣金" + brokeragePrice;
                    this.billService.income(userInfo.getSpreadUid(), "获得推广佣金", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_2.getValue(), brokeragePrice.doubleValue(), balance, mark, order.getId().toString());
                    this.yxUserMapper.incBrokeragePrice(brokeragePrice, userInfo.getSpreadUid());
                    this.backOrderBrokerageTwo(order);
                }
            }
        }
    }

    public void decPrice(Long uid, BigDecimal payPrice) {
        this.yxUserMapper.decPrice(payPrice, uid);
    }

    private BigDecimal computeProductBrokerage(StoreOrderQueryVo order, Brokerage level) {
        List<StoreOrderCartInfo> storeOrderCartInfoList = this.storeOrderCartInfoService
                .list((Wrapper) Wrappers.<StoreOrderCartInfo>lambdaQuery()
                        .in(StoreOrderCartInfo::getCartId,
                                Arrays.asList(order.getCartId().split(","))));
        BigDecimal oneBrokerage = BigDecimal.ZERO;
        BigDecimal twoBrokerage = BigDecimal.ZERO;
        List<String> cartInfos = (List)storeOrderCartInfoList.stream().map(StoreOrderCartInfo::getCartInfo).collect( Collectors.toList());
        Iterator var7 = cartInfos.iterator();

        String storeBrokerageTwoStr;
        while(var7.hasNext()) {
            storeBrokerageTwoStr = (String)var7.next();
            StoreCartQueryVo cart = (StoreCartQueryVo) JSON.parseObject(storeBrokerageTwoStr, StoreCartQueryVo.class);
            StoreProductQueryVo storeProductVO = (StoreProductQueryVo) cart.getProductInfo();
            if (ShopCommonEnum.IS_SUB_1.getValue().equals(storeProductVO.getIsSub())) {
                oneBrokerage = NumberUtil.round(NumberUtil.add(oneBrokerage, NumberUtil.mul(cart.getCartNum(), storeProductVO.getAttrInfo().getBrokerage())), 2);
                twoBrokerage = NumberUtil.round(NumberUtil.add(twoBrokerage, NumberUtil.mul(cart.getCartNum(), storeProductVO.getAttrInfo().getBrokerageTwo())), 2);
            }
        }

        String storeBrokerageRatioStr = this.systemConfigService.getData("store_brokerage_ratio");
        storeBrokerageTwoStr = this.systemConfigService.getData("store_brokerage_two");
        if (!StrUtil.isBlank(storeBrokerageRatioStr) && NumberUtil.isNumber(storeBrokerageRatioStr)) {
            if (!StrUtil.isBlank(storeBrokerageTwoStr) && NumberUtil.isNumber(storeBrokerageTwoStr)) {
                switch(level) {
                    case LEVEL_1:
                        BigDecimal storeBrokerageRatio = NumberUtil.round(NumberUtil.div(storeBrokerageRatioStr, "100"), 2);
                        BigDecimal brokeragePrice = NumberUtil.round(NumberUtil.mul(order.getTotalPrice(), storeBrokerageRatio), 2);
                        return NumberUtil.add(oneBrokerage, brokeragePrice);
                    case LEVEL_2:
                        BigDecimal storeBrokerageTwo = NumberUtil.round(NumberUtil.div(storeBrokerageTwoStr, "100"), 2);
                        BigDecimal storeBrokerageTwoPrice = NumberUtil.round(NumberUtil.mul(order.getTotalPrice(), storeBrokerageTwo), 2);
                        return NumberUtil.add(twoBrokerage, storeBrokerageTwoPrice);
                    default:
                        return BigDecimal.ZERO;
                }
            } else {
                return twoBrokerage;
            }
        } else {
            return oneBrokerage;
        }
    }

    private void backOrderBrokerageTwo(StoreOrderQueryVo order) {
        ShopUser userInfo = (ShopUser)this.getById(order.getUid());
        ShopUser userInfoTwo = (ShopUser)this.getById(userInfo.getSpreadUid());
        if (!ObjectUtil.isNull(userInfoTwo) && userInfoTwo.getSpreadUid() != 0L) {
            ShopUser preUser = (ShopUser)this.getById(userInfoTwo.getSpreadUid());
            BigDecimal brokeragePrice = this.computeProductBrokerage(order, Brokerage.LEVEL_2);
            if (brokeragePrice.compareTo(BigDecimal.ZERO) > 0) {
                double balance = NumberUtil.add(preUser.getBrokeragePrice(), brokeragePrice).doubleValue();
                String mark = "二级推广人" + userInfo.getNickname() + "成功消费" + order.getPayPrice() + "元,奖励推广佣金" + brokeragePrice;
                this.billService.income(userInfoTwo.getSpreadUid(), "获得推广佣金", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_2.getValue(), brokeragePrice.doubleValue(), balance, mark, order.getId().toString());
                this.yxUserMapper.incBrokeragePrice(brokeragePrice, userInfoTwo.getSpreadUid());
            }
        }
    }

    public double setLevelPrice(double price, long uid) {
        LambdaQueryWrapper<UserLevel> wrapper = new LambdaQueryWrapper();
       wrapper.eq(UserLevel::getStatus, ShopCommonEnum.IS_STATUS_1.getValue()).eq(UserLevel::getUid, uid).orderByDesc(UserLevel::getGrade).last("limit 1");
        UserLevel userLevel = (UserLevel)this.userLevelService.getOne(wrapper);
        SystemUserLevel systemUserLevel = new SystemUserLevel();
        if (ObjectUtil.isNotNull(userLevel)) {
            systemUserLevel = (SystemUserLevel)this.systemUserLevelService.getById(userLevel.getLevelId());
        }

        int discount = 100;
        if (ObjectUtil.isNotNull(userLevel)) {
            discount = systemUserLevel.getDiscount().intValue();
        }

        return NumberUtil.mul(NumberUtil.div((float)discount, 100.0F), price);
    }
}
